
//leetcode submit region begin(Prohibit modification and deletion)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 * int val;
 * ListNode next;
 * ListNode() {}
 * ListNode(int val) { this.val = val; }
 * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    /**
     * 第一遍
     * @param lists
     * @return
     */
//    public ListNode mergeKLists(ListNode[] lists) {
//        if (lists.length == 0) return null;
//
//        // 虚拟头节点
//        ListNode dummy = new ListNode(-1);
//        ListNode p = dummy;
//        // 将链表节点放在最小堆里，就可以每次获得k个节点中的最小节点
//        // 这个优先级队列的元素是ListNode，它通过比较函数(a.val - b.val)来定义优先级，即元素的val值越小，优先级越高。
//        PriorityQueue<ListNode> pq = new PriorityQueue<>(
//                lists.length, (a, b)->(a.val - b.val));
//        // 遍历链表数组，将每个头节点放入最小堆中；
//        for (ListNode head : lists) {
//            if (head != null)
//                pq.add(head);
//        }
//
//        while (!pq.isEmpty()) {
//            // 获取最小的节点，放到新链表：
//            // pq.poll() 方法是从优先队列中移除并返回最顶端的元素，如果优先队列为空，则返回 null。
//            ListNode node = pq.poll();
//            p.next = node;
//            // 把当前最小的拿出来给p之后，在找当前最小的后面还有元素没有，有的话，继续放进最小堆，
//            if (node.next != null) {
//                pq.add(node.next);
//            }
//            p = p.next;
//        }
//        return dummy.next;
//    }


    /**
     * 第二遍 2/27
     *
     * @param lists
     * @return
     */
//    public ListNode mergeKLists(ListNode[] lists) {
//        if (lists.length == 0) return null;
//
//        // 新建虚拟头节点
//        ListNode dummy = new ListNode(-1);
//        ListNode p = dummy;
//
//        // 新建优先级队列
//        PriorityQueue<ListNode> pq = new PriorityQueue<>(lists.length, (a, b) -> (a.val - b.val));
//        for (ListNode head : lists) {
//            // 将所有的头节点放进优先级队列
//            if (head != null) pq.add(head);
//        }
//
//        while (!pq.isEmpty()) {
//            // 取出最小的那一个，其实就是最上面的那个
//            ListNode node = pq.poll();
//            p.next = node;
//
//            // 然后将取出的那个节点后面的放进优先级队列，继续比较
//            if (node.next != null) {
//                pq.add(node.next);
//            }
//            p = p.next;
//        }
//        return dummy.next;
//    }


    /**
     * 第三遍 2/28
     *
     * @param lists
     * @return
     */
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists.length == 0) return null;

        // 新建头节点
        ListNode dummy = new ListNode(-1);
        ListNode p = dummy;

        // 新建优先级队列
        PriorityQueue<ListNode> pq = new PriorityQueue<>(lists.length, (a, b) -> (a.val - b.val));
        for (ListNode head: lists) {
            if (head != null) pq.add(head);
        }

        while (!pq.isEmpty()) {
            // 取出最小的那个
            ListNode node = pq.poll();
            p.next = node;

            if (node.next != null) {
                pq.add(node.next);
            }
            p = p.next;
        }
        return dummy.next;
    }
}
//leetcode submit region end(Prohibit modification and deletion)
